package com.ErpCoreWeb.View;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;

import com.ErpCoreModel.Base.AccessType;
import com.ErpCoreModel.Base.CUser;
import com.ErpCoreModel.Framework.CBaseObject;
import com.ErpCoreModel.Framework.CBaseObjectMgr;
import com.ErpCoreModel.Framework.CColumn;
import com.ErpCoreModel.Framework.CTable;
import com.ErpCoreModel.Framework.ColumnType;
import com.ErpCoreModel.Framework.DatabaseType;
import com.ErpCoreModel.Framework.Util;
import com.ErpCoreModel.UI.CView;
import com.ErpCoreModel.UI.CViewDetail;
import com.ErpCoreWeb.Common.Global;
import com.mongodb.BasicDBObject;

/**
 * Servlet implementation class AddMultDetailRecord2
 */
@WebServlet("/AddMultDetailRecord2")
public class AddMultDetailRecord2 extends HttpServlet {
	private static final long serialVersionUID = 1L;

	HttpServletRequest request;
	HttpServletResponse response;
    MultiPartRequestWrapper wrapper ;

    public CUser m_User = null;
    public CTable m_Table = null;
    public CView m_View = null;
    public CViewDetail m_ViewDetail = null;
    public CBaseObjectMgr m_BaseObjectMgr = null;
    public UUID m_guidParentId = Util.GetEmptyUUID();
    AccessType m_ViewAccessType = AccessType.forbide;
    AccessType m_TableAccessType = AccessType.forbide;
    //受限的字段：禁止或者只读权限
    public Map<UUID, AccessType> m_sortRestrictColumnAccessType = new HashMap<UUID, AccessType>();

    /**
     * @see HttpServlet#HttpServlet()
     */
    public AddMultDetailRecord2() {
        super();
        // TODO Auto-generated constructor stub
    }

    //初始化变量
    void initData()
    {
        if (request.getSession().getAttribute("User") == null)
        {
            try {
				response.sendRedirect("../Login.jsp");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
            return ;
        }
        if(IsMultipart())
        	wrapper = (MultiPartRequestWrapper) request;
		try {
			m_User = (CUser) request.getSession().getAttribute("User");

			String vid = GetParameter("vid");
			if (Global.IsNullParameter(vid)) {
				response.getWriter().close();
			}
			m_View = (CView) Global.GetCtx(this.getServletContext())
					.getViewMgr().Find(Util.GetUUID(vid));
			if (m_View == null) {
				response.getWriter().close();
			}
	        m_ViewDetail = (CViewDetail)m_View.getViewDetailMgr().GetFirstObj();
	        if (m_ViewDetail == null)
	        {
	        	response.getWriter().close();
	        }
	        m_Table = (CTable)Global.GetCtx(this.getServletContext()).getTableMgr().Find(m_ViewDetail.getFW_Table_id());

	        if (request.getSession().getAttribute("EditMultMasterDetailViewRecord") == null)
	        {
	        	response.getWriter().close();
	        }
	        CBaseObject objP = (CBaseObject)request.getSession().getAttribute("EditMultMasterDetailViewRecord");
	        m_BaseObjectMgr = objP.GetSubObjectMgr(m_Table.getCode(), CBaseObjectMgr.class);

	        m_sortRestrictColumnAccessType = m_User.GetRestrictColumnAccessTypeList(m_Table);


			String ParentId = GetParameter("ParentId");
			if (!Global.IsNullParameter(ParentId))
				m_guidParentId = Util.GetUUID(ParentId);
			

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    boolean IsMultipart()
    {
    	String ct=request.getContentType();
    	if(Global.IsNullParameter(ct))
    		return false;
    	if(ct.indexOf("multipart/form-data")>-1)
    		return true;
    	return false;
    }
    String GetParameter(String key)
    {
    	if(IsMultipart())
    		return wrapper.getParameter(key);
    	else
    		return request.getParameter(key);
    }
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doProc(request,response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doProc(request,response);
	}
	void doProc(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{

		this.request=request;
		this.response=response;

		response.setContentType("text/html;charset=UTF-8");
		request.setCharacterEncoding("UTF-8");

		//初始化变量
	    initData();
	    //
        String Action = GetParameter("Action");
        if (Action == null) Action = "";

        if (Action.equalsIgnoreCase("PostData"))
        {
        	PostData();
            return ;
        }
        else if (Action.equalsIgnoreCase("Cancel"))
        {
            return ;
        }
	}

    void PostData()
    {
		try {
			if (!ValidateData())
				return;

			CBaseObject objP = (CBaseObject) request.getSession().getAttribute(
					"AddMultMasterDetailViewRecord");
			CBaseObject BaseObject = m_BaseObjectMgr.CreateBaseObject();
			BaseObject.Ctx = m_BaseObjectMgr.Ctx;
			BaseObject.TbCode = m_BaseObjectMgr.TbCode;

			CColumn colP = (CColumn) objP.getTable().getColumnMgr()
					.Find(m_ViewDetail.getPrimaryKey());
			CColumn colF = (CColumn) m_Table.getColumnMgr().Find(
					m_ViewDetail.getForeignKey());
			BaseObject.SetColValue(colF, objP.GetColValue(colP));

			boolean bHasVisible = false;
			// foreach (CBaseObject objCIVD in
			// m_ViewDetail.ColumnInViewDetailMgr.GetList())
			for (CBaseObject objCol : m_Table.getColumnMgr().GetList()) {
				// CColumnInViewDetail civd = (CColumnInViewDetail)objCIVD;

				// CColumn col =
				// (CColumn)m_Table.ColumnMgr.Find(civd.FW_Column_id);
				CColumn col = (CColumn) objCol;
				if (col == null)
					continue;
				// 判断禁止和只读权限字段
				if (m_sortRestrictColumnAccessType.containsKey(col.getId())) {
					AccessType accessType = m_sortRestrictColumnAccessType
							.get(col.getId());
					if (accessType == AccessType.forbide)
						continue;
					// 只读只在界面控制,有些默认值需要只读也需要保存数据
					// else if (accessType == AccessType.read)
					// continue;
				}
				//

				if (col.getCode().equalsIgnoreCase("id"))
					continue;
				else if (col.getCode().equalsIgnoreCase("Created")) {
					BaseObject.SetColValue(col,
							new Date(System.currentTimeMillis()));
					continue;
				} else if (col.getCode().equalsIgnoreCase("Creator")) {
					CUser user = (CUser) request.getSession().getAttribute(
							"User");
					BaseObject.SetColValue(col, user.getId());
					continue;
				} else if (col.getCode().equalsIgnoreCase("Updated"))
					continue;
				else if (col.getCode().equalsIgnoreCase("Updator")) {
					// BaseObject.SetColValue(col, Program.User.Id);
					continue;
				}

				if (col.getColType() == ColumnType.object_type) {
					File postfile = wrapper.getFiles("_" + col.getCode())[0];
					if (postfile != null && postfile.length() > 0) {
						String sFileName = wrapper.getFileNames("_"
								+ col.getCode())[0];
						if (sFileName.lastIndexOf('\\') > -1)// 有些浏览器不带路径
							sFileName = sFileName.substring(sFileName
									.lastIndexOf('\\'));

						byte[] byteFileName = sFileName.getBytes("UTF8");
						byte[] byteValue = new byte[(int) (254 + postfile
								.length())];
						byte[] byteData = new byte[(int) postfile.length()];
						InputStream in = new FileInputStream(postfile);
						in.read(byteData);

						System.arraycopy(byteFileName, 0, byteValue, 0,
								byteFileName.length);
						System.arraycopy(byteData, 0, byteValue, 254,
								byteData.length);

						BaseObject.SetColValue(col, byteValue);
					}
				} else if (col.getColType() == ColumnType.path_type) {
					String sUploadPath = col.getUploadPath();
					if (!sUploadPath.endsWith("\\"))
						sUploadPath += "\\";
					File dir = new File(sUploadPath);
					if (!dir.exists())
						dir.mkdir();

					File postfile = wrapper.getFiles("_" + col.getCode())[0];
					if (postfile != null && postfile.length() > 0) {
						String sFileName = wrapper.getFileNames("_"
								+ col.getCode())[0];
						if (sFileName.lastIndexOf('\\') > -1)// 有些浏览器不带路径
							sFileName = sFileName.substring(sFileName
									.lastIndexOf('\\'));

						String sExt = "";
						int idx = sFileName.lastIndexOf('.');
						if (idx > -1)
							sExt = sFileName.substring(idx);
						// File fi = new File(sUploadPath + sFileName);
						UUID guid = UUID.randomUUID();
						String sDestFile = String.format("%s%s", guid
								.toString().replace("-", ""), sExt);

						byte[] buffer = new byte[1024];
						FileOutputStream fos = new FileOutputStream(sUploadPath
								+ sDestFile);
						InputStream in = new FileInputStream(postfile);
						try {
							int num = 0;
							while ((num = in.read(buffer)) > 0) {
								fos.write(buffer, 0, num);
							}
						} catch (Exception e) {
							e.printStackTrace(System.err);
						} finally {
							in.close();
							fos.close();
						}

						String sVal = String.format("%s%s", sDestFile,
								sFileName);
						BaseObject.SetColValue(col, sVal);
					}
				} else if (col.getColType() == ColumnType.bool_type) {
					String val = wrapper.getParameter("_" + col.getCode());
					if (!Global.IsNullParameter(val)
							&& val.equalsIgnoreCase("on"))
						BaseObject.SetColValue(col, true);
					else
						BaseObject.SetColValue(col, false);
				} else if (col.getColType() == ColumnType.datetime_type) {
					String val = wrapper.getParameter("_" + col.getCode());
					if (!Global.IsNullParameter(val)) {
						SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
						if(val.indexOf(" ")>0)
							sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
						Date V;
						try {
							V = sdf.parse(val);
							BaseObject.SetColValue(col, V);
						} catch (ParseException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				} else
					BaseObject.SetColValue(col,
							wrapper.getParameter("_" + col.getCode()));
				bHasVisible = true;
			}
			if (!bHasVisible) {
				// Response.Write("没有可修改字段！");
				response.getWriter().print(
						"<script>alert('没有可修改字段！');</script>");
				return;
			}
			if (!m_BaseObjectMgr.AddNew(BaseObject, true)) {
				// Response.Write("添加失败！");
				response.getWriter().print("<script>alert('添加失败！');</script>");
				return;
			}
			// 在iframe里访问外面,需要parent.parent.
			// Response.Write("<script>parent.parent.grid.loadData(true);parent.parent.$.ligerDialog.close();</script>");
			response.getWriter()
					.print("<script>parent.parent.onOkAddMasterDetailViewRecord();</script>");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
  //验证数据
    boolean ValidateData()
    {
		try {
			// foreach (CBaseObject objCIV in m_View.ColumnInViewMgr.GetList())
			for (CBaseObject objCol : m_Table.getColumnMgr().GetList()) {
				// CColumnInView civ = (CColumnInView)objCIV;

				// CColumn col =
				// (CColumn)m_Table.ColumnMgr.Find(civ.FW_Column_id);
				CColumn col = (CColumn) objCol;
				if (col == null)
					continue;
				// 判断禁止和只读权限字段
				if (m_sortRestrictColumnAccessType.containsKey(col.getId())) {
					AccessType accessType = m_sortRestrictColumnAccessType
							.get(col.getId());
					if (accessType == AccessType.forbide)
						continue;
					// 只读只在界面控制,有些默认值需要只读也需要保存数据
					// else if (accessType == AccessType.read)
					// continue;
				}
				//

				if (col.getCode().equalsIgnoreCase("id"))
					continue;
				else if (col.getCode().equalsIgnoreCase("Created")) {
					continue;
				} else if (col.getCode().equalsIgnoreCase("Creator")) {
					continue;
				} else if (col.getCode().equalsIgnoreCase("Updated"))
					continue;
				else if (col.getCode().equalsIgnoreCase("Updator")) {
					// BaseObject.SetColValue(col, Program.User.Id);
					continue;
				}

				String val = wrapper.getParameter("_" + col.getCode());
				if (!col.getAllowNull() && Global.IsNullParameter(val)) {
					response.getWriter().print(
							String.format("<script>alert('%s不允许空！');</script>",
									col.getName()));
					return false;
				}
				if (col.getColType() == ColumnType.string_type) {
					if (val.length() > col.getColLen()) {
						response.getWriter()
								.print(String
										.format("<script>alert('%s长度不能超过{1}！');</script>",
												col.getName(), col.getColLen()));
						return false;
					}
				} else if (col.getColType() == ColumnType.datetime_type) {
					if (!Global.IsNullParameter(val)) {
						try {
							SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
							if(val.indexOf(" ")>0)
								sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
							Date V2 = sdf.parse(val);
						} catch (Exception e) {
							response.getWriter()
									.print(String
											.format("<script>alert('%s日期格式错误！');</script>",
													col.getName()));
							return false;
						}
					}
				} else if (col.getColType() == ColumnType.int_type
						|| col.getColType() == ColumnType.long_type) {
					if (!Util.IsInt(val)) {
						response.getWriter().print(
								String.format(
										"<script>alert('%s为整型数字！');</script>",
										col.getName()));
						return false;
					}
				} else if (col.getColType() == ColumnType.numeric_type) {
					if (!Util.IsNum(val)) {
						response.getWriter().print(
								String.format(
										"<script>alert('%s为数字！');</script>",
										col.getName()));
						return false;
					}
				} else if (col.getColType() == ColumnType.guid_type
						|| col.getColType() == ColumnType.ref_type) {
					if (!Global.IsNullParameter(val)) {
						try {
							UUID guid = Util.GetUUID(val);
						} catch (Exception e) {
							response.getWriter()
									.print(String
											.format("<script>alert('%s为GUID格式！');</script>",
													col.getName()));
							return false;
						}
					}
				}

				// 唯一性字段判断
				if (col.getIsUnique()) {
					if (!IsUniqueValue(col, val))
						return false;
				}
			}
			return true;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
    }

    //唯一性字段判断
    boolean IsUniqueValue(CColumn col, String val)
    {
        if (col.getColType() == ColumnType.string_type
            || col.getColType() == ColumnType.text_type
            || col.getColType() == ColumnType.path_type)
        {
            CBaseObjectMgr BaseObjectMgr = Global.GetCtx(this.getServletContext()).FindBaseObjectMgrCache(m_Table.getCode(), m_guidParentId);
            if (BaseObjectMgr != null)
            {
                List<CBaseObject> lstObj = BaseObjectMgr.GetList();
                for(CBaseObject obj : lstObj)
                {
                	if(obj.m_arrNewVal.get(col.getCode().toLowerCase()).StrVal.endsWith(val))
                		return false;
                }
                
            }
            else
            {
                BaseObjectMgr = new CBaseObjectMgr();
                BaseObjectMgr.TbCode = m_Table.getCode();
                BaseObjectMgr.Ctx = Global.GetCtx(this.getServletContext());

                if (BaseObjectMgr.Ctx.getMainDB().m_DbType == DatabaseType.MongoDb)
                {
                	BasicDBObject query = new BasicDBObject();  
                    query.put(col.getBsonCode(), val);
                    List<CBaseObject> lstObj2 = BaseObjectMgr.GetList(query, null, 0, 0);
                    if (lstObj2.size() > 0)
	                    return false;
                }
                else
                {
	                String sWhere = String.format(" [%s]='%s'",col.getCode(),val);
	                List<CBaseObject> lstObj = BaseObjectMgr.GetList(sWhere);
	                if (lstObj.size() > 0)
	                    return false;
                }
            }
        }
        else if (col.getColType() == ColumnType.datetime_type)
        {
            CBaseObjectMgr BaseObjectMgr = Global.GetCtx(this.getServletContext()).FindBaseObjectMgrCache(m_Table.getCode(), m_guidParentId);
            if (BaseObjectMgr != null)
            {
                List<CBaseObject> lstObj = BaseObjectMgr.GetList();
                for(CBaseObject obj : lstObj)
                {
		            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); 
		            if(val.indexOf(" ")>0)
		            	sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
                	Date V2;
					try {
						V2 = sdf.parse(val);
	                	if(obj.m_arrNewVal.get(col.getCode().toLowerCase()).DatetimeVal.equals(V2))
	                		return false;
					} catch (ParseException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
                }
            }
            else
            {
                BaseObjectMgr = new CBaseObjectMgr();
                BaseObjectMgr.TbCode = m_Table.getCode();
                BaseObjectMgr.Ctx = Global.GetCtx(this.getServletContext());

                if (BaseObjectMgr.Ctx.getMainDB().m_DbType == DatabaseType.MongoDb)
                {
                	BasicDBObject query = new BasicDBObject();  
                    query.put(col.getBsonCode(), val);
                    List<CBaseObject> lstObj2 = BaseObjectMgr.GetList(query, null, 0, 0);
                    if (lstObj2.size() > 0)
	                    return false;
                }
                else
                {
	                String sWhere = String.format(" [%s]='%s'", col.getCode(), val);
	                List<CBaseObject> lstObj = BaseObjectMgr.GetList(sWhere);
	                if (lstObj.size() > 0)
	                    return false;
                }
            }
        }
        else if (col.getColType() == ColumnType.int_type
            || col.getColType() == ColumnType.long_type
            || col.getColType() == ColumnType.numeric_type)
        {
            CBaseObjectMgr BaseObjectMgr = Global.GetCtx(this.getServletContext()).FindBaseObjectMgrCache(m_Table.getCode(), m_guidParentId);
            if (BaseObjectMgr != null)
            {
                List<CBaseObject> lstObj = BaseObjectMgr.GetList();
                if (col.getColType() == ColumnType.int_type)
                {
                	for(CBaseObject obj : lstObj)
                    {
                    	if(obj.m_arrNewVal.get(col.getCode().toLowerCase()).IntVal.equals(Integer.valueOf(val)))
                    		return false;
                    }
                }
                else if (col.getColType() == ColumnType.long_type)
                {
                	for(CBaseObject obj : lstObj)
                    {
                    	if(obj.m_arrNewVal.get(col.getCode().toLowerCase()).LongVal.equals(Long.valueOf(val)))
                    		return false;
                    }
                }
                else
                {
                	for(CBaseObject obj : lstObj)
                    {
                    	if(obj.m_arrNewVal.get(col.getCode().toLowerCase()).DoubleVal.equals(Double.valueOf(val)))
                    		return false;
                    }
                }
            }
            else
            {
                BaseObjectMgr = new CBaseObjectMgr();
                BaseObjectMgr.TbCode = m_Table.getCode();
                BaseObjectMgr.Ctx = Global.GetCtx(this.getServletContext());

                if (BaseObjectMgr.Ctx.getMainDB().m_DbType == DatabaseType.MongoDb)
                {
                	BasicDBObject query = new BasicDBObject();  
                    query.put(col.getBsonCode(), val);
                    List<CBaseObject> lstObj2 = BaseObjectMgr.GetList(query, null, 0, 0);
                    if (lstObj2.size() > 0)
	                    return false;
                }
                else
                {
	                String sWhere = String.format(" [%s]=%s", col.getCode(), val);
	                List<CBaseObject> lstObj = BaseObjectMgr.GetList(sWhere);
	                if (lstObj.size() > 0)
	                    return false;
                }
            }
        }
        else if (col.getColType() == ColumnType.guid_type
        || col.getColType() == ColumnType.ref_type)
        {
            CBaseObjectMgr BaseObjectMgr = Global.GetCtx(this.getServletContext()).FindBaseObjectMgrCache(m_Table.getCode(), m_guidParentId);
            if (BaseObjectMgr != null)
            {
                List<CBaseObject> lstObj = BaseObjectMgr.GetList();

            	for(CBaseObject obj : lstObj)
                {
                	if(obj.m_arrNewVal.get(col.getCode().toLowerCase()).GuidVal.equals(Util.GetUUID(val)))
                		return false;
                }
            }
            else
            {
                BaseObjectMgr = new CBaseObjectMgr();
                BaseObjectMgr.TbCode = m_Table.getCode();
                BaseObjectMgr.Ctx = Global.GetCtx(this.getServletContext());

                if (BaseObjectMgr.Ctx.getMainDB().m_DbType == DatabaseType.MongoDb)
                {
                	BasicDBObject query = new BasicDBObject();  
                    query.put(col.getBsonCode(), val);
                    List<CBaseObject> lstObj2 = BaseObjectMgr.GetList(query, null, 0, 0);
                    if (lstObj2.size() > 0)
	                    return false;
                }
                else
                {
	                String sWhere = String.format(" [%s]='%s'", col.getCode(), val);
	                List<CBaseObject> lstObj = BaseObjectMgr.GetList(sWhere);
	                if (lstObj.size() > 0)
	                    return false;
                }
            }
        }

        return true;
    }
}
